﻿using System;
using System.Collections.Generic;
using System.Data.Objects.SqlClient;
using System.Linq;
using System.Reflection;
using System.Text;
using ZBJF.Warranty.Common.Common;
using ZBJF.Warranty.Common.Enums.System;
using ZBJF.Warranty.Model;
using ZBJF.Warranty.Model.ViewModel.BaseQueryModel;
using ZBJF.Warranty.Model.ViewModel.Log;

namespace ZBJF.Warranty.BLL
{
    public partial class OpreateLogsService
    {
        public OpreateLogs Load(long id)
        {
            return LoadEntities(o => o.ID == id).FirstOrDefault();
        }

        public bool Add(OpreateLogs entity)
        {
            var lastOpreateLog = LoadLastOpreateLog(entity.LogTableName, entity.LogTablePKID);
            entity.CostTotalSecond = (int)(lastOpreateLog == null ? 0 : (entity.CreatedTime - lastOpreateLog.CreatedTime).TotalSeconds);
            return AddEntities(entity).ID > 0;
        }

        public bool AddOpreateLogs<T1, T2>(OpreateLogs entity, T1 source, T2 current, OpreateType type = OpreateType.Update)
        {
            try
            {
                var content = type != OpreateType.Update ? JSON.Encode(current) : GetDifferenceContent(entity.LogTableName, source, current);
                entity.LogContent = content;
                if (string.IsNullOrEmpty(entity.LogContent))
                    return true;
                return Add(entity);
            }
            catch (Exception)
            {
                return false;
            }
        }

        public OpreateLogs LoadLastOpreateLog(string logTableName, long logTablePKID)
        {
            return LoadEntities(o => o.LogTableName.Equals(logTableName) && o.LogTablePKID == logTablePKID).OrderByDescending(o => o.ID).FirstOrDefault();
        }

        public IQueryable<OpreateLogs> GetPagingList(OpreateLogsModel model, out int total)
        {
            var expressionWhere = PredicateExtensions.True<OpreateLogs>();
            if (!string.IsNullOrEmpty(model.LogTableName))
            {
                expressionWhere = expressionWhere.And(o => o.LogTableName.Equals(model.LogTableName));
            }
            if (model.LogTablePKID > 0)
            {
                expressionWhere = expressionWhere.And(o => o.LogTablePKID == model.LogTablePKID);
            }
            if (!string.IsNullOrEmpty(model.LogContent))
            {
                expressionWhere = expressionWhere.And(o => o.LogContent.Contains(model.LogContent));
            }
            if (!string.IsNullOrEmpty(model.OpreateUserAccount))
            {
                expressionWhere = expressionWhere.And(o => o.OpreateUserAccount.Equals(model.OpreateUserAccount));
            }
            if (model.CreatedTimeStart.HasValue)
            {
                expressionWhere = expressionWhere.And(o => o.CreatedTime >= model.CreatedTimeStart);
            }
            if (model.CreatedTimeEnd.HasValue)
            {
                expressionWhere = expressionWhere.And(o => o.CreatedTime < SqlFunctions.DateAdd("dd", 1, model.CreatedTimeEnd));
            }
            if (model.CostTotalSecondMin > 0)
            {
                expressionWhere = expressionWhere.And(o => o.CostTotalSecond >= model.CostTotalSecondMin);
            }
            if (model.CostTotalSecondMax > 0)
            {
                expressionWhere = expressionWhere.And(o => o.CostTotalSecond < model.CostTotalSecondMax);
            }

            return LoadPagerEntities<OpreateLogs>(model.PageIndex, model.iDisplayLength, out total, expressionWhere, model.iSorts);
        }

        public string GetFieldDesc(string tableName, string fieldName)
        {
            var desc = DbSession.OpreateLogsRepository.GetFieldDesc(tableName, fieldName);
            return string.IsNullOrEmpty(desc) ? fieldName : desc;
        }
        /// <summary>
        /// 获取修改信息
        /// </summary>
        /// <typeparam name="T1"></typeparam>
        /// <typeparam name="T2"></typeparam>
        /// <param name="tableName">表名</param>
        /// <param name="source"></param>
        /// <param name="current"></param>
        /// <returns></returns>
        public string GetDifferenceContent<T1, T2>(string tableName, T1 source, T2 current)
        {
            Type sourceType = source.GetType();
            Type currentType = current.GetType();
            PropertyInfo[] sourceTypePropertys = sourceType.GetProperties();
            var sbResult = new StringBuilder();
            foreach (PropertyInfo p in sourceTypePropertys)
            {
                if (!p.PropertyType.IsPrimitive) //不是基元类型不比较
                {
                    if (p.PropertyType != typeof(string) && !IsNullableBaseDataType(p.PropertyType))
                        continue;
                }
                if ("CreateBy,CreateTime,CreatedTime,LastModifyBy,LastModifyTime".Contains(p.Name))//修改字段不记录日志
                    continue;
                string name = p.Name;
                var sourceValue = p.GetValue(source, null);
                object currentValue = null;
                var currentProperty = currentType.GetProperty(name);
                if (currentProperty != null)
                {
                    currentValue = currentProperty.GetValue(current, null);
                }
                var sourceValueStr = sourceValue == null ? "" : sourceValue.ToString();
                var currentValueStr = currentValue == null ? "" : currentValue.ToString();
                if (sourceValueStr != currentValueStr)
                {
                    sbResult.AppendFormat("字段[{0}]:由【{1}】改为【{2}】<br/>", GetFieldDesc(tableName, name), sourceValueStr, currentValueStr);
                }
            }
            return sbResult.ToString();
        }
        /// <summary>
        /// 判断是否是可空基元类型
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
        bool IsNullableBaseDataType(Type t)
        {
            return (t == typeof(sbyte?) || t == typeof(byte?) || t == typeof(short?) || t == typeof(ushort?) ||
                    t == typeof(int?) || t == typeof(uint?) || t == typeof(long?) || t == typeof(ulong?) ||
                    t == typeof(char?) || t == typeof(float?) || t == typeof(double?) || t == typeof(bool?));
        }
    }
}